package com.aplink.generic.util.validation;

import java.util.ArrayList;
import java.util.regex.Pattern;

import android.text.TextUtils;
import android.widget.EditText;

import com.aplink.generic.GenericFragment;
import com.aplink.generic.constant.type.ControlType;
import com.aplink.generic.constant.type.EditTextType;
import com.aplink.generic.database.DatabaseHelper;
import com.aplink.generic.database.SqlMethods;
import com.aplink.generic.pojo.controlspec.ControlSpec;
import com.aplink.generic.pojo.controlspec.EditTextSpec;
import com.aplink.generic.widgets.ApLinkBaseView;
import com.aplink.generic.widgets.ApLinkEditText;
import com.aplink.sg.R;

public class ControlValidation {
    public static ControlValidation getInstance() {
        return new ControlValidation();
    }

    public ValidationResult isFormValidate(
            final GenericFragment dataEntryActivity,
            final String validationGroupName) {
        final ValidationResult validationResult = new ValidationResult();
        boolean isValid = true;
        final ArrayList<ControlSpec> validationControls = dataEntryActivity
                .getValidationGroups().get(validationGroupName);
        for (final ControlSpec controlSpec : validationControls) {
            final String validationGroup = controlSpec.getValidationGroup();
            if (validationGroup == null) {
                continue;
            }
            if (!controlSpec.getValidationGroup().equalsIgnoreCase(
                    validationGroup)) {
                continue;
            }
            final ApLinkBaseView baseView = dataEntryActivity
                    .getAPLinkViewByID(controlSpec.getIDName());
            if (controlSpec.getControlType().equals(ControlType.EDITTEXT)) {
                String value = "";
                if ((baseView.getAttribute() != null)
                        && (baseView.getAttribute().getValue() != null)) {
                    value = baseView.getAttribute().getValue().toString();
                }
                final ApLinkEditText customEdittext = (ApLinkEditText) baseView;
                final EditTextSpec editTextSpecFormat = (EditTextSpec) controlSpec;
                final Validation validation = editTextSpecFormat
                        .getValidation();
                final EditText editText = customEdittext.getEditText();
                final boolean isNoBlank = validation.isNoBlank();
                final boolean isNoDuplicate = validation.isNoDuplicate();
                final int minLength = editTextSpecFormat.getMinLength();
                final int maxLength = editTextSpecFormat.getMaxLength();
                if (isNoDuplicate) {
                    final String whereClause = SqlMethods.getInstance()
                            .equal(controlSpec.getMappingName(), value)
                            .toString();
                    final boolean isExists = DatabaseHelper.getInstance()
                            .isExists(dataEntryActivity.getContentData(),
                                    whereClause);
                    if (isExists) {
                        editText.setError(validation.getDuplicate()
                                .getMessage());
                        isValid = false;
                        continue;
                    }
                }
                if (isNoBlank && value.isEmpty()) {
                    if (TextUtils.isEmpty(validation.getBlankRule()
                            .getMessage())) {
                        editText.setError("This field is required");
                    } else {
                        editText.setError(validation.getBlankRule()
                                .getMessage());
                    }
                    isValid = false;
                    continue;
                }
                if (value.length() < minLength) {
                    editText.setError(" longer than " + minLength
                            + " characters");
                    isValid = false;
                    continue;
                }
                if (value.length() > maxLength) {
                    editText.setError(" no longer than " + maxLength
                            + " characters");
                    isValid = false;
                    continue;
                }

                if (editTextSpecFormat.getDataInputType().equals(
                        EditTextType.EMAIL)) {
                    final Pattern email = android.util.Patterns.EMAIL_ADDRESS;
                    if (!email.matcher(value).matches()) {
                        editText.setError("This field is invalid, Please enter your email");
                        isValid = false;
                        continue;
                    }
                }

                if (editTextSpecFormat.getDataInputType().equals(
                        EditTextType.PHONE)) {
                    final Pattern email = android.util.Patterns.PHONE;
                    if (!email.matcher(value).matches()) {
                        editText.setError("This field is invalid, Please enter phone numbers");
                        isValid = false;
                        continue;
                    }
                }

                if (editTextSpecFormat.getDataInputType().equals(
                        EditTextType.PASSWORD)) {
                    final String passwordRegex = editTextSpecFormat
                            .getRegularExpression();
                    if (passwordRegex == null) {
                        continue;
                    }
                    final Pattern password = Pattern.compile(passwordRegex);
                    if (!password.matcher(value).matches()) {
                        final String errorMessage = dataEntryActivity
                                .getString(R.string.aplink__generic_invalid_pass);
                        editText.setError(errorMessage);
                        isValid = false;
                        continue;
                    }
                }
            }
        }
        validationResult.setValid(isValid);
        return validationResult;
    }

}
